﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Events;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FurStudy.Web.Entry
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    // 加载自定义配置
                    config.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true);
                    // [拓展] 获取项目目录 .BaseDirectory ；获取网站根目录 Directory.GetCurrentDirectory()
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.Inject()
                              .UseStartup<Startup>()
                              .UseKestrel(option => // 设置Api超时请求时间
                              {
                                  option.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(20); // 默认2min
                                  option.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(20); // 默认30s
                              });
                })
                // 添加默认日志拓展
                .UseSerilogDefault(config =>//默认集成了控制台和文件方式。如需自定义写入，则传入需要写入的介质即可：
                {
                    string date = DateTime.Now.ToString("yyyy-MM-dd");//按时间创建文件夹
                    string outputTemplate = "{NewLine}【{Level:u3}】{Timestamp:yyyy-MM-dd HH:mm:ss.fff}" +
                    "{NewLine}#Msg#{Message:lj}" +
                    "{NewLine}#Pro #{Properties:j}" +
                    "{NewLine}#Exc#{Exception}" +
                    new string('-', 50);//输出模板

                    ///1.输出所有restrictedToMinimumLevel：LogEventLevel类型
                    config
                        //.MinimumLevel.Debug() // 所有Sink的最小记录级别
                        //.MinimumLevel.Override("Microsoft", LogEventLevel.Fatal)
                        //.Enrich.FromLogContext()
                        .WriteTo.Console(outputTemplate: outputTemplate)
                        .WriteTo.File($"_log/{date}/application.log",
                                outputTemplate: outputTemplate,
                                restrictedToMinimumLevel: LogEventLevel.Information,
                                rollingInterval: RollingInterval.Day,//日志按日保存，这样会在文件名称后自动加上日期后缀
                                                                    //rollOnFileSizeLimit: true,          // 限制单个文件的最大长度
                                                                    //retainedFileCountLimit: 10,         // 最大保存文件数,等于null时永远保留文件。
                                                                    //fileSizeLimitBytes: 10 * 1024,      // 最大单个文件大小
                                encoding: Encoding.UTF8            // 文件字符编码
                            )

                    #region 2.按LogEventLevel.输出独立发布/单文件

                    ///2.1仅输出 LogEventLevel.Debug 类型
                    .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Debug)//筛选过滤
                        .WriteTo.File($"_log/{date}/{LogEventLevel.Debug}.log",
                            outputTemplate: outputTemplate,
                            rollingInterval: RollingInterval.Day,//日志按日保存，这样会在文件名称后自动加上日期后缀
                            encoding: Encoding.UTF8            // 文件字符编码
                            )
                                                    )

                    ///2.2仅输出 LogEventLevel.Error 类型
                    .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Error)//筛选过滤
                        .WriteTo.File($"_log/{date}/{LogEventLevel.Error}.log",
                            outputTemplate: outputTemplate,
                            rollingInterval: RollingInterval.Day,//日志按日保存，这样会在文件名称后自动加上日期后缀
                            encoding: Encoding.UTF8            // 文件字符编码
                            )
                                                    )

                    #endregion 按LogEventLevel 独立发布/单文件

                        ;
                }); ;
        }
    }
}
